package com.itheima.stock.service.impl;

import com.google.common.base.Strings;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.UserService;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.resp.LoginRespVo;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.ResponseCode;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author GAQ
 * @create 2022-05-30
 * @Description
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 用户登录功能
     *
     * @param vo
     * @return
     */
    @Override
    public R<LoginRespVo> login(LoginReqVo vo) {
        //1.判断参数是否合法
        if (vo == null || Strings.isNullOrEmpty(vo.getUsername()) || Strings.isNullOrEmpty(vo.getPassword())
                || Strings.isNullOrEmpty(vo.getCode()) || Strings.isNullOrEmpty(vo.getRkey())) {
            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
        }
        //从redis中取出改key对应的验证码
        String rCheckCode = (String) redisTemplate.opsForValue().get("CK:" + vo.getRkey());
        if (rCheckCode==null || !rCheckCode.equals(vo.getCode())){
            //响应验证码输入错误
            return R.error(ResponseCode.SYSTEM_VERIFY_CODE_ERROR.getMessage());
        }

        redisTemplate.delete("CK:" + vo.getRkey());

        //2.根据用户名查询用户信息
        SysUser info = sysUserMapper.getUserInfoByName(vo.getUsername());
        //3.判断查询的用户信息是否为空
        if (info == null) {
            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
        }
        //4.判断输入的明文密码与数据库中的密文密码进行匹配
        boolean result = passwordEncoder.matches(vo.getPassword(), info.getPassword());
        //4.1 如果密码匹配不成功
        if (!result) {
            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
        }
        //4.2 成功则返回用户信息
        LoginRespVo loginRespVo = new LoginRespVo();
        //spring中封装的一个工具类,保证复制的双方具有共同的属性名称
        BeanUtils.copyProperties(info, loginRespVo);
        return R.ok(loginRespVo);
    }

    /**
     * 获取登录校验码
     *
     * @return
     */
    @Override
    public R<Map> generateCaptcha() {
        //1.生成4位数字验证码
        String checkCode = RandomStringUtils.randomNumeric(4);
        //模拟session 2.获取全局唯一id
        String sessionId = String.valueOf(idWorker.nextId());
        //为redis保存的数据的key取一个业务前缀，方便后期维护
        String rkey = "CK:" + sessionId;
        //验证码存入redis中，并设置有效期1分钟
        redisTemplate.opsForValue().set(rkey, checkCode, 300, TimeUnit.SECONDS);
        //3.组装数据
        Map info = new HashMap();
        info.put("code", checkCode);
        info.put("rkey", sessionId);
        return R.ok(info);
    }
}
